#include <bits/stdc++.h>
const int MAXN = 1e5 + 10;
using namespace std;

struct block{ int l, r;};

int T, n, m, L, V, ans1, ans2, p[MAXN], l[MAXN], r[MAXN];
struct node{
    int d, v0, a;
} arr[MAXN];
vector<block> S;

bool catchable(int mid, int i){
    int vp = 2 * arr[i].a * (p[mid] - arr[i].d) + arr[i].v0 * arr[i].v0;
    return vp > V * V;
}

bool related(int l1, int r1, int l2, int r2){
    if(l1 > l2){
        swap(l1, l2);
        swap(r1, r2);
    }
    return r1 >= l2;
}

int main(){
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    scanf("%d", &T);
    while(T--){
        scanf("%d %d %d %d", &n, &m, &L, &V);
        ans1 = 0, ans2 = 0;
        for(int i = 1; i <= n; i++)
            scanf("%d %d %d", &arr[i].d, &arr[i].v0, &arr[i].a);

        for(int i = 1; i <= m; i++)
            scanf("%d", p + i);

        for(int i = 1; i <= n; i++){
            l[i] = r[i] = 0;
            if(arr[i].d > p[m]) continue;
            int j = lower_bound(p + 1, p + m + 1, arr[i].d) - p;
            if(arr[i].a == 0 && arr[i].v0 > V)
                l[i] = j, r[i] = m, ans1++;

            if(arr[i].a > 0){
                int lft = j, rgt = m, mid, res = -1;
                while(lft <= rgt){
                    mid = (lft + rgt) >> 1;
                    if(catchable(mid, i)){
                        res = mid;
                        rgt = mid - 1;
                    }
                    else lft = mid + 1;
                }

                if(res != -1)
                    ans1++, l[i] = res, r[i] = m;
            }

            if(arr[i].a < 0){
                int lft = j, rgt = m, mid, res = -1;
                while(lft <= rgt){
                    mid = (lft + rgt) >> 1;
                    if(catchable(mid, i)){
                        res = mid;
                        lft = mid + 1;
                    }
                    else rgt = mid - 1;
                }
                if(res != -1)
                    ans1++, l[i] = j, r[i] = res;
            }
        }

        for(int i = 1; i <= n; i++)
            printf("%d %d\n", l[i], r[i]);

        //block_merge
        block cur;
        cur.l = l[1];
        cur.r = r[1];
        ans2 = 1;
        S.push_back(cur);
        for(int i = 2; i <= n; i++){
            bool flag = false;
            for(int j = 0; j < S.size(); j++){
                if(related(S[j].l, S[j].r, l[i], r[i])){
                    flag = true;
                    S[j].l = max(S[j].l, l[i]);
                    S[j].r = min(S[j].l, r[i]);
                    break;
                }
            }
            if(!flag){
                ans2++;
                block temp;
                temp.l = l[i];
                temp.r = r[i];
                S.push_back(temp);
            }
        }
        printf("%d %d\n", ans1, ans2);
    }
    return 0;
}


